#coding=utf-8
from scapy.all import *

MACWhiteList=["a8:15:4d:e2:b6:a8","06:5f:a7:76:75:d8","44:c8:74:ee:2f:7a"]
SSIDWhiteList=["cmcc-2"]
#MACWhiteList.append()
fakeAPList={}
#统计每种类型的帧数量
timeout=5
lastSequenceControl={}
start=True
'''
SC域,SequenceControl包含了SequenceNumber和FragmentNumber字段，fragmentnumber占低四位
每一个beancon帧的sequencenumber都比上一个+1，又因为低在beancon帧中为0，所以换成十进制SC每次都+16
'''

def updateFakeAPList(SSID,currentMAC):
    if (SSID in fakeAPList.keys()):
        if (currentMAC not in fakeAPList[SSID]):
                fakeAPList[SSID].append(currentMAC)
    else:
        fakeAPList[SSID] = [currentMAC]
'''
True:设备MAC在白名单中或者SSID不属于白名单
'''
def baseWhiteList(SSID,currentMAC):
    res=True
    if (SSID in SSIDWhiteList):
        if (currentMAC not in MACWhiteList):
            res=False
    return res
'''
只处理设备MAC在白名单中的包
'''
def baseSequenceControl(packet):
    res=True
    currentMAC=packet.addr2
    if(currentMAC not in lastSequenceControl.keys()):
        lastSequenceControl[currentMAC]=packet.SC
        return True

    lastSC = lastSequenceControl[currentMAC]
    #print(lastSC)
    currentSC = packet.SC
    #print(currentSC)
    if (abs(currentSC - lastSC) > 30 * 16):
        print(currentSC)
        print(lastSC)
        print(abs(currentSC - lastSC))
        res=False
    else:
        lastSequenceControl[currentMAC]=currentSC
    return res

def PacketHandler(packet):
    if(packet.haslayer(Dot11Beacon)):
        SSID = str(packet.info,encoding="utf8")
        currentMAC = packet.addr2
        flag=baseWhiteList(SSID,currentMAC)
        if (flag == False):
            updateFakeAPList(SSID,currentMAC)
        else:
            if(currentMAC in MACWhiteList and baseSequenceControl(packet)==False):
                updateFakeAPList(SSID,currentMAC)

def EltHandler(packet):
    if (packet.haslayer(Dot11Beacon)):
        ssid=None
        channel=None

        crypto = set()
        p = packet[Dot11Elt]
        while isinstance(p, Dot11Elt):
            info=p.info
            print(type(info))
            if p.ID == 0:
                ssid=p.info
            elif p.ID == 3:
                channel= ord(p.info)
            elif p.ID==48:
                crypto.add("WPA2")
                print("WPA2")
            elif p.ID == 221:
                if isinstance(info,bytes):
                    print(info)
                    # if info.startswith('\x00p\xf2\x01\x00'):
                    #     print()
                    #     crypto.add("WPA")
            p = p.payload
        # if not crypto:
        #     if 'privacy' in cap:
        #         crypto.add("WEP")
        #     else:
        #         crypto.add("OPN")


if __name__ == "__main__":
    print('the program is running ,please wait...')

    # cap = sniff(offline='DisassociationAttack.pcapng', prn=lambda x:x.summary())

    while (True):
        APList = []
        fakeAPList = {}
        lastSequenceControl = {}
        # cap = sniff(offline="fakeap.pcapng", lfilter=lambda p: (Dot11Beacon in p), prn=EltHandler, timeout=timeout)
        cap = sniff(iface="wlp2s0",prn=PacketHandler, timeout=timeout)
        for (k, v) in fakeAPList.items():
            print("[+]FakeAP Found!,the SSID is " + k + " the MAC is ", v)
        print('current scan is done,the next will begin')
        print('--------------------------------------------------------------')